#!/usr/bin/env node

/**
 * 真实代币交易测试脚本
 * ⚠️ 警告：此脚本会执行真实的区块链交易，消耗真实资金！
 */

const axios = require('axios');
const {
  Connection,
  Keypair,
  PublicKey,
  Transaction,
  SystemProgram,
  sendAndConfirmTransaction,
  LAMPORTS_PER_SOL,
} = require('@solana/web3.js');
const {
  getAssociatedTokenAddress,
  createAssociatedTokenAccountInstruction,
  createTransferInstruction,
  getAccount,
  TOKEN_PROGRAM_ID,
} = require('@solana/spl-token');
const fs = require('fs');

// 配置
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:7172';
const DEVNET_RPC = 'https://api.devnet.solana.com';

// 代币信息
const TOKEN_MINT = '4C5SJj6Gfd86jTS7PgtYmjGjGxrG9GAuLUmQ47vGnQPc'; // 您创建的代币
const YOUR_ADDRESS = 'shTdKtBScJMC4GkKmasiE9iMKrtZnMFUtwVTdSXsKac'; // 您的地址

// 真实交易测试数据 (较小金额，安全测试)
const realTestTrades = [
  {
    type: 'BUY',
    tokenAmount: 100, // 减少到 100 代币
    solAmount: 0.01, // 减少到 0.01 SOL
    description: '小额真实购买测试 - 100 代币',
  },
  {
    type: 'BUY',
    tokenAmount: 250,
    solAmount: 0.025,
    description: '中等真实购买测试 - 250 代币',
  },
];

// 生成测试钱包 (作为卖家)
function generateTestWallet() {
  const keypair = Keypair.generate();
  const walletData = {
    publicKey: keypair.publicKey.toString(),
    secretKey: Array.from(keypair.secretKey),
  };

  const filename = `seller-wallet-${Date.now()}.json`;
  fs.writeFileSync(filename, JSON.stringify(walletData, null, 2));
  
  console.log(`💾 生成卖家钱包: ${filename}`);
  console.log(`📍 卖家地址: ${keypair.publicKey.toString()}`);
  
  return { keypair, filename };
}

// 从私钥文件加载钱包
function loadWallet(filePath) {
  try {
    const walletData = JSON.parse(fs.readFileSync(filePath, 'utf8'));
    const keypair = Keypair.fromSecretKey(new Uint8Array(walletData.secretKey));
    return keypair;
  } catch (error) {
    console.error(`❌ 无法加载钱包 ${filePath}:`, error.message);
    return null;
  }
}

// 真实代币购买交易
async function executeRealTokenPurchase(buyerKeypair, sellerKeypair, tokenAmount, solAmount) {
  console.log(`🔥 执行真实代币购买交易...`);
  
  const connection = new Connection(DEVNET_RPC, 'confirmed');
  const tokenMint = new PublicKey(TOKEN_MINT);
  
  const buyer = buyerKeypair.publicKey;
  const seller = sellerKeypair.publicKey;
  
  console.log(`📊 交易详情:`);
  console.log(`- 代币: ${TOKEN_MINT}`);
  console.log(`- 买家: ${buyer.toString()}`);
  console.log(`- 卖家: ${seller.toString()}`);
  console.log(`- 购买数量: ${tokenAmount} 代币`);
  console.log(`- 支付金额: ${solAmount} SOL`);
  
  try {
    // 检查余额
    const buyerBalance = await connection.getBalance(buyer);
    const sellerBalance = await connection.getBalance(seller);
    
    console.log(`💰 交易前余额:`);
    console.log(`- 买家: ${(buyerBalance / LAMPORTS_PER_SOL).toFixed(6)} SOL`);
    console.log(`- 卖家: ${(sellerBalance / LAMPORTS_PER_SOL).toFixed(6)} SOL`);
    
    if (buyerBalance < solAmount * LAMPORTS_PER_SOL + 10000) {
      throw new Error('买家SOL余额不足');
    }
    
    // 获取代币账户地址
    const sellerTokenAccount = await getAssociatedTokenAddress(tokenMint, seller);
    const buyerTokenAccount = await getAssociatedTokenAddress(tokenMint, buyer);
    
    // 检查卖家代币余额
    let sellerTokenBalance;
    try {
      const account = await getAccount(connection, sellerTokenAccount);
      sellerTokenBalance = account.amount;
      console.log(`💎 卖家代币余额: ${sellerTokenBalance.toString()}`);
      
      if (sellerTokenBalance < BigInt(tokenAmount * Math.pow(10, 9))) {
        throw new Error('卖家代币余额不足');
      }
    } catch (error) {
      throw new Error(`卖家没有此代币或余额不足: ${error.message}`);
    }
    
    // 检查买家代币账户
    let buyerAccountExists = false;
    try {
      await getAccount(connection, buyerTokenAccount);
      buyerAccountExists = true;
      console.log(`💎 买家代币账户已存在`);
    } catch {
      console.log(`💎 买家代币账户不存在，将创建`);
    }
    
    console.log(`🔨 构建交易...`);
    
    // 创建交易
    const transaction = new Transaction();
    
    // 如果需要，创建买家代币账户
    if (!buyerAccountExists) {
      console.log(`📝 添加创建代币账户指令`);
      transaction.add(
        createAssociatedTokenAccountInstruction(
          buyer,
          buyerTokenAccount,
          buyer,
          tokenMint,
        ),
      );
    }
    
    // 添加代币转账指令（从卖家到买家）
    console.log(`📝 添加代币转账指令`);
    const tokenAmountWithDecimals = BigInt(tokenAmount * Math.pow(10, 9));
    transaction.add(
      createTransferInstruction(
        sellerTokenAccount,
        buyerTokenAccount,
        seller,
        tokenAmountWithDecimals,
      ),
    );
    
    // 添加SOL转账指令（从买家到卖家）
    console.log(`📝 添加SOL支付指令`);
    transaction.add(
      SystemProgram.transfer({
        fromPubkey: buyer,
        toPubkey: seller,
        lamports: solAmount * LAMPORTS_PER_SOL,
      }),
    );
    
    // 设置交易参数
    const { blockhash } = await connection.getLatestBlockhash('confirmed');
    transaction.recentBlockhash = blockhash;
    transaction.feePayer = buyer;
    
    console.log(`🔏 签署交易...`);
    
    // 签署交易
    transaction.partialSign(buyerKeypair, sellerKeypair);
    
    console.log(`📡 发送交易到区块链...`);
    
    // 发送并确认交易
    const signature = await sendAndConfirmTransaction(
      connection,
      transaction,
      [buyerKeypair, sellerKeypair],
      {
        commitment: 'confirmed',
        preflightCommitment: 'confirmed',
      },
    );
    
    console.log(`✅ 交易成功！`);
    console.log(`🔗 交易签名: ${signature}`);
    console.log(`🔍 Solscan: https://solscan.io/tx/${signature}?cluster=devnet`);
    console.log(`🔍 Solana Explorer: https://explorer.solana.com/tx/${signature}?cluster=devnet`);
    
    return {
      success: true,
      signature: signature,
      solscanUrl: `https://solscan.io/tx/${signature}?cluster=devnet`,
      explorerUrl: `https://explorer.solana.com/tx/${signature}?cluster=devnet`,
    };
    
  } catch (error) {
    console.log(`❌ 交易失败: ${error.message}`);
    return {
      success: false,
      error: error.message,
    };
  }
}

// 主函数
async function realTradeTest() {
  console.log('🔥 真实代币交易测试');
  console.log('='.repeat(60));
  console.log('⚠️  警告：此脚本会执行真实的区块链交易！');
  console.log('⚠️  警告：会消耗真实的 SOL 和代币！');
  console.log('='.repeat(60));
  console.log(`🪙 代币地址: ${TOKEN_MINT}`);
  console.log(`👤 您的地址: ${YOUR_ADDRESS}`);
  console.log(`📡 API地址: ${API_URL}`);
  console.log(`🌐 RPC地址: ${DEVNET_RPC}`);
  
  // 检查命令行参数
  const args = process.argv.slice(2);
  if (!args.includes('--confirm')) {
    console.log(`
❌ 安全检查失败！

为了安全起见，执行真实交易需要明确确认。
请使用以下命令运行：

  node scripts/real-trade-test.js --confirm

⚠️  再次提醒：
- 此脚本会执行真实的区块链交易
- 会消耗真实的 SOL 和代币
- 交易一旦执行无法撤销
- 请确保您了解风险并有足够余额

如果您只想测试功能，请使用模拟版本：
  node scripts/trade-test.js
`);
    process.exit(1);
  }
  
  try {
    // 1. 检查后端服务
    console.log('\n1️⃣ 检查后端服务...');
    await axios.get(`${API_URL}/api/health`);
    console.log('✅ 后端服务正常');
    
    // 2. 检查您的账户余额
    console.log('\n2️⃣ 检查您的账户余额...');
    const connection = new Connection(DEVNET_RPC, 'confirmed');
    const yourPublicKey = new PublicKey(YOUR_ADDRESS);
    const yourBalance = await connection.getBalance(yourPublicKey);
    const yourSolBalance = yourBalance / LAMPORTS_PER_SOL;
    
    console.log(`💰 您的 SOL 余额: ${yourSolBalance.toFixed(6)} SOL`);
    
    if (yourSolBalance < 0.1) {
      console.log('❌ 您的 SOL 余额不足，需要至少 0.1 SOL 进行测试');
      process.exit(1);
    }
    
    // 3. 生成卖家钱包
    console.log('\n3️⃣ 生成测试卖家钱包...');
    const sellerWallet = generateTestWallet();
    
    // 4. 您需要提供买家私钥
    console.log('\n4️⃣ 加载买家钱包...');
    console.log('⚠️  需要您的私钥文件来执行交易');
    console.log('请创建一个包含您私钥的 JSON 文件，格式如下：');
    console.log(`
{
  "publicKey": "${YOUR_ADDRESS}",
  "secretKey": [您的私钥数组]
}
`);
    
    // 检查是否有买家钱包文件
    const buyerWalletFile = 'buyer-wallet.json';
    if (!fs.existsSync(buyerWalletFile)) {
      console.log(`❌ 未找到买家钱包文件: ${buyerWalletFile}`);
      console.log('请创建此文件后重新运行脚本');
      process.exit(1);
    }
    
    const buyerKeypair = loadWallet(buyerWalletFile);
    if (!buyerKeypair) {
      console.log('❌ 无法加载买家钱包');
      process.exit(1);
    }
    
    console.log(`✅ 买家钱包加载成功: ${buyerKeypair.publicKey.toString()}`);
    
    // 5. 警告并等待确认
    console.log('\n5️⃣ 最后确认...');
    console.log('即将执行真实交易，按 Ctrl+C 取消，或等待 5 秒后自动开始...');
    
    await new Promise(resolve => setTimeout(resolve, 5000));
    
    // 6. 执行交易测试
    console.log('\n6️⃣ 开始执行真实交易测试...');
    const results = [];
    
    for (let i = 0; i < realTestTrades.length; i++) {
      const trade = realTestTrades[i];
      console.log(`\n🎯 执行交易 ${i + 1}/${realTestTrades.length}`);
      console.log(`📝 ${trade.description}`);
      
      const result = await executeRealTokenPurchase(
        buyerKeypair,
        sellerWallet.keypair,
        trade.tokenAmount,
        trade.solAmount
      );
      
      result.trade = trade;
      results.push(result);
      
      if (i < realTestTrades.length - 1) {
        console.log('⏸️ 等待 10 秒后进行下一笔交易...');
        await new Promise(resolve => setTimeout(resolve, 10000));
      }
    }
    
    // 7. 生成报告
    console.log('\n7️⃣ 生成交易报告...');
    generateRealTradeReport(results);
    
    // 8. 清理
    console.log('\n8️⃣ 清理临时文件...');
    console.log(`删除临时卖家钱包: ${sellerWallet.filename}`);
    fs.unlinkSync(sellerWallet.filename);
    
    console.log('\n🎉 真实交易测试完成!');
    
  } catch (error) {
    console.log('❌ 测试过程中发生错误:', error.message);
    if (error.response?.data) {
      console.log('错误详情:', JSON.stringify(error.response.data, null, 2));
    }
  }
}

// 生成真实交易报告
function generateRealTradeReport(results) {
  console.log('\n📊 真实交易报告');
  console.log('='.repeat(50));
  
  const successful = results.filter(r => r.success);
  const failed = results.filter(r => !r.success);
  
  console.log(`✅ 成功交易: ${successful.length}/${results.length}`);
  console.log(`❌ 失败交易: ${failed.length}/${results.length}`);
  
  if (successful.length > 0) {
    console.log(`\n🔗 成功交易链接:`);
    successful.forEach((result, index) => {
      console.log(`${index + 1}. 交易签名: ${result.signature}`);
      console.log(`   Solscan: ${result.solscanUrl}`);
      console.log(`   Explorer: ${result.explorerUrl}`);
    });
  }
  
  if (failed.length > 0) {
    console.log(`\n❌ 失败交易:`);
    failed.forEach((result, index) => {
      console.log(`${index + 1}. ${result.trade.description} - ${result.error}`);
    });
  }
  
  // 保存报告
  const reportData = {
    timestamp: new Date().toISOString(),
    type: 'REAL_TRADE_TEST',
    tokenMint: TOKEN_MINT,
    traderAddress: YOUR_ADDRESS,
    summary: {
      totalTrades: results.length,
      successfulTrades: successful.length,
      failedTrades: failed.length,
      successRate: (successful.length / results.length) * 100,
    },
    trades: results,
  };
  
  const reportFile = `real-trade-report-${Date.now()}.json`;
  fs.writeFileSync(reportFile, JSON.stringify(reportData, null, 2));
  console.log(`\n💾 详细报告已保存到: ${reportFile}`);
}

// 显示帮助信息
if (process.argv.includes('--help') || process.argv.includes('-h')) {
  console.log(`
🔥 真实代币交易测试脚本

⚠️  警告：此脚本会执行真实的区块链交易，消耗真实资金！

用法:
  node scripts/real-trade-test.js --confirm

前置条件:
  1. 创建 buyer-wallet.json 文件，包含您的私钥
  2. 确保您的账户有足够的 SOL 余额 (至少 0.1 SOL)
  3. 确保您了解交易风险

文件格式 (buyer-wallet.json):
{
  "publicKey": "您的地址",
  "secretKey": [您的私钥数组]
}

代币信息:
  - 代币地址: ${TOKEN_MINT}
  - 您的地址: ${YOUR_ADDRESS}

安全提醒:
  - 此脚本会消耗真实的 SOL
  - 交易一旦执行无法撤销
  - 建议先用小金额测试
  - 私钥文件请妥善保管

如需模拟测试，请使用:
  node scripts/trade-test.js
`);
  process.exit(0);
}

// 运行真实交易测试
realTradeTest();
